
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>ArrayList Java中最常用的动态数组实现 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>ArrayList Java中最常用的动态数组实现 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">ArrayList 实现了 RandomAccess 接口，这表明了它的什么关键特性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">实现了 RandomAccess 接口表明 ArrayList 支持快速随机访问。其 get 和 set 方法直接对内部数组进行操作，时间复杂度为 O(1)。</div>
          </div>
          <div class="card-source">来源: 1.1 类继承结构, 4.1 随机访问方法get与set</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">ArrayList 内部的核心数据结构是什么？其默认的初始容量是多少？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">ArrayList 内部使用一个名为 `elementData` 的 `transient Object[]` 数组来存储元素。其默认的初始容量 `DEFAULT_CAPACITY` 是 10。</div>
          </div>
          <div class="card-source">来源: 1.2 核心成员变量</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">当使用无参构造函数 `new ArrayList()` 创建实例时，内部数组会立即被分配容量吗？如果不会，它在何时才会被分配容量？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">使用无参构造函数时，并不会立即创建容量为10的数组，而是将内部数组 `elementData` 指向一个共享的空数组 `DEFAULTCAPACITY_EMPTY_ELEMENTDATA`。只有在第一次添加元素时，数组才会扩容到默认的10。</div>
          </div>
          <div class="card-source">来源: 2. ArrayList的构造方法</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">请描述 ArrayList 的核心动态扩容策略。当需要扩容时，它的容量会增加多少？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">ArrayList 的核心扩容在 `grow` 方法中实现。当需要扩容时，新容量通常会增加为旧容量的1.5倍（`oldCapacity + (oldCapacity >> 1)`）。扩容的实现方式是创建一个更大的新数组，然后将旧数组中的所有元素复制到新数组中。</div>
          </div>
          <div class="card-source">来源: 3.2 核心扩容方法grow</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在 ArrayList 中调用 `remove(int index)` 方法为什么在最坏情况下的时间复杂度是 O(n)？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">因为删除元素时，需要将被删除元素位置之后的所有元素都向前移动一位，这个操作是通过 `System.arraycopy` 完成的。在最坏的情况下（例如，删除第一个元素），需要移动 n-1 个元素，因此时间复杂度为 O(n)。</div>
          </div>
          <div class="card-source">来源: 4.2 删除元素方法remove</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在已知需要存储大量元素的情况下，如何优化 ArrayList 的性能以避免多次扩容？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">如果预先知道需要存储的大致元素数量，应该使用带有初始容量的构造函数 `new ArrayList<>(initialCapacity)` 来一次性分配足够的空间。或者，在添加大量元素前，可以调用 `ensureCapacity(int minCapacity)` 方法来预先扩容，从而避免在循环中发生多次代价高昂的数组复制操作。</div>
          </div>
          <div class="card-source">来源: 5.1 容量管理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">为什么说 ArrayList 不适合频繁在列表的中间位置进行插入或删除操作？在这种场景下，有什么更好的替代选择？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">因为 ArrayList 在中间位置插入或删除元素时，需要移动该位置之后的所有元素，这会导致性能下降，时间复杂度为O(n)。如果需要频繁地在列表开头或中间进行插入/删除，更好的选择是使用 LinkedList，因为它在这些操作上效率更高。</div>
          </div>
          <div class="card-source">来源: 5.2 避免频繁的中间位置插入和删除</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">ArrayList 本身是线程安全的吗？如果不是，文档中提到了哪两种使其线程安全的替代方案？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">ArrayList 不是线程安全的。文档中提到的线程安全替代方案有两种：1. 使用 `Collections.synchronizedList(new ArrayList<>())` 方法创建一个线程安全的包装类。2. 使用 `java.util.concurrent` 包下的 `CopyOnWriteArrayList` 类。</div>
          </div>
          <div class="card-source">来源: 5.3 注意线程安全问题</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">为什么在迭代 ArrayList 时直接调用 list.remove() 会抛出 ConcurrentModificationException？正确的删除方式是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">因为在使用迭代器（包括 for-each 循环）遍历时，如果通过集合自身的方法（如 `list.remove()`）修改了集合的结构，会导致迭代器的状态与集合的状态不一致，从而抛出异常。正确的做法是使用迭代器自身的 `iterator.remove()` 方法，或者在Java 8及以上版本中使用 `list.removeIf()` 方法。</div>
          </div>
          <div class="card-source">来源: 5.5 迭代时的修改问题</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
